//=========================================================================
// Copyright (C) 2024 The C++ Component Model(COMO) Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//=========================================================================

/**
 * Persistent Memory Library Tests
 */

#include <config.h>
#include <stdio.h>
#include <time.h>
#include "check_common.h"
#include "pmalloc.h"

#define PM_CAPACITY 1024LL * 1024 * 1024 * 10
#define PM_MAX_ALLOCSIZE 1024LL * 1024 * 1024 * 8

TEST(PmallocTest, TestPmclear) {
    //printf("Start checking test in block size %lld . \n", PM_MAX_ALLOCSIZE);
    int fd = open("pmclear_ds.dat", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ASSERT_GE(fd, 0) << "open file fail";

    void *md = pmalloc_attach(fd, nullptr, PM_CAPACITY, false);
    ASSERT_NE(md, nullptr) << "pmalloc_attach fail";

    init_random();
    size_t j = 0;
    size_t cntsz = number_binary_length(PM_MAX_ALLOCSIZE);
    size_t fcount, i;
    size_t counters[cntsz];

    long fpattern[PMALLOC_KEYS];

    int quitflag = 0;

    for (i = 0;  i < cntsz;  i++) {
        counters[i] = -1;
    }

    for (j = 1;  j <= PM_MAX_ALLOCSIZE && !quitflag;  j *= 2) {
        gen_pattern(fpattern, PMALLOC_KEYS, 2);
        clear_keydata(md, fpattern, PMALLOC_KEYS);
        fcount = refill_keydata(md, j);
        counters[number_binary_length(j) - 1] = fcount;
        // system( "read -n 1 -s -p \"Press any key to continue...\"; echo" );
    }

    for (j = 1;  j <= PM_MAX_ALLOCSIZE && !quitflag;  j *= 2) {
        gen_pattern(fpattern, PMALLOC_KEYS, 0);
        clear_keydata(md, fpattern, PMALLOC_KEYS);
        fcount = refill_keydata(md, j);
        if (counters[number_binary_length(j) - 1] != fcount) {
            printf(ANSI_COLOR_RED
                   "(1)Fill count error! %zx <> %zx \n" ANSI_COLOR_RESET,
                   counters[number_binary_length(j)], fcount);
            quitflag = 1;
            break;
        }
        // system( "read -n 1 -s -p \"Press any key to continue...\"; echo" );
    }

    ///////////////////////////

    for (j = PM_MAX_ALLOCSIZE;  (j > 0) && !quitflag;  j /= 2) {
        gen_pattern(fpattern, PMALLOC_KEYS, 2);
        clear_keydata(md, fpattern, PMALLOC_KEYS);
        fcount = refill_keydata(md, j);
        if (counters[number_binary_length(j) - 1] != fcount) {
            printf(ANSI_COLOR_RED
                   "(2)Fill count error! %zx <> %zx \n" ANSI_COLOR_RESET,
                   counters[number_binary_length(j)], fcount);
            quitflag = 1;
            break;
        }
        // system( "read -n 1 -s -p \"Press any key to continue...\"; echo" );
    }

    for (j = PM_MAX_ALLOCSIZE;  (j > 0) && !quitflag;  j /= 2) {
        gen_pattern(fpattern, PMALLOC_KEYS, 1);
        clear_keydata(md, fpattern, PMALLOC_KEYS);
        fcount = refill_keydata(md, j);
        if (counters[number_binary_length(j) - 1] != fcount) {
            printf(ANSI_COLOR_RED
                   "(3)Fill count error! %zx <> %zx \n" ANSI_COLOR_RESET,
                   counters[number_binary_length(j)], fcount);
            quitflag = 1;
            break;
        }
        // system( "read -n 1 -s -p \"Press any key to continue...\"; echo" );
    }

    pmalloc_detach(md);
    close(fd);
    //printf("PM Closed.\n");
    ASSERT_EQ(quitflag, 0);
}

/*原项目在CTest下的测试用例代码*/

// int main() {
//     printf("Start checking test in block size %lld . \n", PM_MAX_ALLOCSIZE);
//     int fd = open("pmclear_ds.dat", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
//     if (fd < 0) {
//         printf(ANSI_COLOR_RED "Open test data file failure." ANSI_COLOR_RESET);
//         return 1;
//     }

//     void *md = pmalloc_attach(fd, nullptr, PM_CAPACITY);

//     init_random();

//     size_t j = 0, cntsz = number_binary_length(PM_MAX_ALLOCSIZE), fcount, i;

//     size_t counters[cntsz];

//     long fpattern[PMALLOC_KEYS];

//     int quitflag = 0;

//     for (i = 0; i < cntsz; ++i) counters[i] = -1;

//     for (j = 1; j <= PM_MAX_ALLOCSIZE && !quitflag; j *= 2) {
//         gen_pattern(fpattern, PMALLOC_KEYS, 2);
//         clear_keydata(md, fpattern, PMALLOC_KEYS);
//         fcount = refill_keydata(md, j);
//         counters[number_binary_length(j) - 1] = fcount;
//         // system( "read -n 1 -s -p \"Press any key to continue...\"; echo" );
//     }
//     for (j = 1; j <= PM_MAX_ALLOCSIZE && !quitflag; j *= 2) {
//         gen_pattern(fpattern, PMALLOC_KEYS, 0);
//         clear_keydata(md, fpattern, PMALLOC_KEYS);
//         fcount = refill_keydata(md, j);
//         if (counters[number_binary_length(j) - 1] != fcount) {
//             printf(ANSI_COLOR_RED
//                    "Fill count error! %zx <> %zx \n" ANSI_COLOR_RESET,
//                    counters[number_binary_length(j)], fcount);
//             quitflag = 1;
//             break;
//         }
//         // system( "read -n 1 -s -p \"Press any key to continue...\"; echo" );
//     }

//     for (j = PM_MAX_ALLOCSIZE; j > 0 && !quitflag; j /= 2) {
//         gen_pattern(fpattern, PMALLOC_KEYS, 2);
//         clear_keydata(md, fpattern, PMALLOC_KEYS);
//         fcount = refill_keydata(md, j);
//         if (counters[number_binary_length(j) - 1] != fcount) {
//             printf(ANSI_COLOR_RED
//                    "Fill count error! %zx <> %zx \n" ANSI_COLOR_RESET,
//                    counters[number_binary_length(j)], fcount);
//             quitflag = 1;
//             break;
//         }
//         // system( "read -n 1 -s -p \"Press any key to continue...\"; echo" );
//     }
//     for (j = PM_MAX_ALLOCSIZE; j > 0 && !quitflag; j /= 2) {
//         gen_pattern(fpattern, PMALLOC_KEYS, 1);
//         clear_keydata(md, fpattern, PMALLOC_KEYS);
//         fcount = refill_keydata(md, j);
//         if (counters[number_binary_length(j) - 1] != fcount) {
//             printf(ANSI_COLOR_RED
//                    "Fill count error! %zx <> %zx \n" ANSI_COLOR_RESET,
//                    counters[number_binary_length(j)], fcount);
//             quitflag = 1;
//             break;
//         }
//         // system( "read -n 1 -s -p \"Press any key to continue...\"; echo" );
//     }

//     pmalloc_detach(md);
//     close(fd);
//     printf("PM Closed.\n");
//     return quitflag;
// }
